package com.ruoyi.tools.sms.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.ruoyi.Apps.Utils.EmailCodeUtil;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.model.SmsCodeBody;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.I18nException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.sms.SmsCodeRedisService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.ConfigKeyUtil;
import com.ruoyi.tools.sms.ISmsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;

@Component
public class SmsServiceImpl implements ISmsService {

    @Value("${sms.accessKeyId}")
    private String accessKeyId;

    @Value("${sms.accessKeySecret}")
    private String accessKeySecret;

    @Value("${sms.domain}")
    private String domain;
    @Value("${sms.signName}")
    private String signName;
    @Value("${sms.templateCode}")
    private String templateCode;

    private String openKey = "sys.send.phonemsg";

    @Autowired
    private RedisCache redisCache;

    private static final Logger log = LoggerFactory.getLogger(SmsServiceImpl.class);

    @Autowired
    private SmsCodeRedisService smsCodeService;

    @Override
    public String sendSms(SmsCodeBody codeBody) {

        String phoneNumber = codeBody.getPhone();

        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(codeBody.getUuid(), "");
        String captcha = redisCache.getCacheObject(verifyKey);
        if (!Objects.equals(codeBody.getCode(), captcha)) {
            throw new I18nException("user.jcaptcha.error");
        }

        String randomCode = EmailCodeUtil.getRandomCode();
        Boolean openFlag = ConfigKeyUtil.getBoolean(openKey);
        if (!openFlag) {
            // 不发送短信 直接返回
            String uuid = smsCodeService.saveCodeToRedis(phoneNumber,randomCode);
            log.info("code="+randomCode+"|phoneNumber="+phoneNumber+"|uuid="+uuid);
            return uuid;
        }
        //设置超时时间-可自行调整
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain(domain);
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phoneNumber);
        //request.putQueryParameter("SignName", "圻峰科技");//直接取signName就会提示签名不合法 这样写就可以发送短信
        request.putQueryParameter("SignName", signName);//直接取signName就会提示签名不合法 这样写就可以发送短信
        request.putQueryParameter("TemplateCode", templateCode);
        JSONObject object = new JSONObject();
        try {
            object.put("code",randomCode);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        String templateParam =object.toString();
        request.putQueryParameter("TemplateParam", templateParam);
        //LogAdapter.JavaUtilLog log;
        try {
            //请求失败这里会抛ClientException异常
            CommonResponse response = client.getCommonResponse(request);
           // log.info("阿里云短信服务返回消息:"+response.getData());
            log.info("阿里云短信服务返回消息:"+response.getData());
            // 使用alibaba的fastjson
            Map<String, Object> map=  JSON.parseObject(response.getData());
            if ("isv.BUSINESS_LIMIT_CONTROL".equals(map.get("Code"))) {
                throw new ServiceException("号码受到流控限制");
            }
            if ("isv.VOICE_ROBOT_CALLEE_LIMIT".equals(response.getData())) {
                throw new ServiceException("被叫号码超过1000");
            }
            if ("isv.COMPLAINT_REJECT".equals(response.getData())) {
                throw new ServiceException("防骚扰拦截");
            }

            if (("OK").equals(map.get("Code"))){
                String uuid = smsCodeService.saveCodeToRedis(phoneNumber,randomCode);
                log.info("code="+randomCode+"|phoneNumber="+phoneNumber+"|uuid="+uuid);
                return uuid;
            }else{
                return null;
            }
        } catch (ClientException e) {
            log.error("--短信失败---");
            log.error(e.getMessage());
        }
        return null;

    }


    @Override
    public String toString() {
        return "SmsServiceImpl{" +
                "accessKeyId='" + accessKeyId + '\'' +
                ", accessKeySecret='" + accessKeySecret + '\'' +
                ", domain='" + domain + '\'' +
                ", signName='" + signName + '\'' +
                ", templateCode='" + templateCode + '\'' +
                '}';
    }
}
